import SelectTable from '../SelectTable'

const buildColumn = (schema, config={}, mini, index) => {
  const column = {
    title: config.title || schema.title,
    key: config.key || schema.key,
    dataIndex: config.dataIndex || schema.key,
    valueType: config.tableValueType || buildValueType(schema, config, mini),
    formItemProps: config.formItemProps || buildFormItemProps(schema, config, mini),
    fieldProps: config.fieldProps || buildFieldProps(schema, config, mini),
    convertValue: config.convertValue || buildConvertValue(schema, config, mini),
    transform: config.transform || buildTransform(schema, config, mini),
    width: config.width || buildWidth(schema, config, mini),
    colProps: config.colProps || buildColProps(schema, config, mini),
    hideInSearch: config.hideInSearch || buildHideInSearch(schema, config, mini),
    hideInTable: config.hideInTable || buildHideInTable(schema, config, mini),
    sorter: config.sorter  || true,
    sort: config.sort || index,
    render: buildRender(schema, config, mini),
    search: buildSearch(schema, config, mini),
    ...config
  }
  const formItem = buildFormItem(schema)
  if(formItem){ column.renderFormItem = formItem }
  return column
}

const buildValueType = (schema, config, mini) => {
  if(schema.primary){ return "indexBorder" }
  if(schema.key == 'password'){ return 'password' }
  if(config.relation){ return 'select' }
  switch (schema.type) {
    case 'bit': return 'switch'
    case 'int': return 'digit'
    case 'tinyint': return 'digit'
    case 'mediumint': return 'digit'
    case 'bigint': return 'digit'
    case 'decimal': return 'digit'
    case 'double': return 'digit'
    case 'float': return 'digit'
    case 'date': return 'dateRange'
    case 'time': return 'dateRange'
    case 'datetime': return 'dateRange'
    case 'timestamp': return 'dateRange'
    case 'year': return 'dateYear'
    case 'varchar': return 'text'
    case 'char': return 'text'
    case 'tinytext': return 'textarea'
    case 'mediumtext': return 'textarea'
    case 'text': return 'textarea'
    case 'longtext': return 'textarea'
    case 'json': return 'code'
    case 'binary': return 'image'
    case 'varbinary': return 'image'
    case 'tinyblob': return 'image'
    case 'blob': return 'image'
    case 'mediumblob': return 'image'
    case 'longblob': return 'image'
    default: return 'text';
  }
}

//Form.Item控件的配置
const buildFormItemProps = (schema, config, mini) => { }

//输入控件的配置
const buildFieldProps = (schema, config, mini) => {
  switch (schema.type) {
    case 'int': return { precision: 0 }
    case 'tinyint': return { precision: 0 }
    case 'mediumint': return { precision: 0 }
    case 'bigint': return { precision: 0 }
    default: return {};
  }
}

const buildFormItem = (schema, config, mini) => {
  if(schema.relation){ return (form,config)=>(<SelectTable fieldProps={config} table={schema.relation.table} multi={false}/>) }
}

const buildRender = (schema, config, mini) => {
  if(schema.primary){ return (node, record, index) => <a onClick={()=>onDetail(record)}>{record[schema.key]}</a> }
  if(config.relation){ return (node, record, index) => <a onClick={()=>addTab(schema.relation.table, { option:'DETAIL', id: record[schema.key] })}>{record[schema.relation_name]}</a> }
  if(['date', 'time', 'datetime', 'timestamp'].includes(schema.type)){ return (node, record, index) => record[schema.key] }
  return (node, record, index) => node
}

const buildTransform = (schema, config, mini) => {
  return (value) => { return value }
}

const buildConvertValue = (schema, config, mini) => {
  return (obj)=> obj
}

const buildSearch = (schema, config, mini) => {
  const like = { transform: (value) =>{ const req = {}; req[schema.key] = ['LIKE', `%${value}%`]; return value ? req : null }}
  const equest = { transform: (value) =>{ const req = {}; req[schema.key] = value; return value ? req : null }}
  const between = { transform: (value) =>{ if(value && value.length == 2){ const req = {}; req[schema.key] = ['between', [value[0], value[1]]]; return req } return null}}

  switch (schema.type) {
    case 'bit': return equest
    case 'int': return equest
    case 'tinyint': return equest
    case 'mediumint': return equest
    case 'bigint': return equest
    case 'decimal': return equest
    case 'double': return equest
    case 'float': return equest
    case 'date': return between
    case 'time': return mini ? false : between
    case 'datetime': return mini ? false : between
    case 'timestamp': return mini ? false : between
    case 'year': return mini ? false : equest
    case 'varchar': return like
    case 'char': return like
    default: return false;
  }
}

const buildHideInSearch = (schema, config, mini) => {
  if(['lastedit_date', 'create_date', 'password'].includes(schema.key)){ return true }
  switch (schema.type) {
    case 'tinytext': return true
    case 'mediumtext': return true
    case 'text': return true
    case 'longtext': return true
    case 'json': return true
    case 'binary': return true
    case 'varbinary': return true
    case 'tinyblob': return true
    case 'blob': return true
    case 'mediumblob': return true
    case 'longblob': return true
    case 'date': return mini
    case 'time': return mini
    case 'datetime': return mini
    case 'timestamp': return mini
    case 'year': return mini
    default: return false;
  }
}

const buildHideInTable = (schema, config, mini) => {
  if(['lastedit_date', 'create_date', 'password'].includes(schema.key)){ return true }
  switch (schema.type) {
    case 'tinytext': return true
    case 'mediumtext': return true
    case 'text': return true
    case 'longtext': return true
    case 'json': return true
    case 'binary': return true
    case 'varbinary': return true
    case 'tinyblob': return true
    case 'blob': return true
    case 'mediumblob': return true
    case 'longblob': return true
    default: return false;
  }
}

const buildWidth = (schema, config, mini) => {
  switch (schema.type) {
    case 'tinytext': return "xxl"
    case 'mediumtext': return "xxl"
    case 'text': return "xxl"
    case 'longtext': return "xxl"
    case 'json': return "xxl"
  }
  return "md"
}

const buildColProps = (schema, config, mini) => {
  switch (schema.type) {
    case 'tinytext': return { xs: 24, md: 24 }
    case 'mediumtext': return { xs: 24, md: 24 }
    case 'text': return { xs: 24, md: 24 }
    case 'longtext': return { xs: 24, md: 24 }
    case 'json': return { xs: 24, md: 24 }
  }
  return { xs: 24, md: 12 }
}

export default (table_config, mini=false) => {
  const schemas = table_config.schema || []
  const columns = table_config.config?.columns || []
  const tableExtended = table_config.config?.tableExtended || []
  const forms = schemas.map((schema, index)=>buildColumn(schema, {
    ...columns[schema.key], 
    table:table_config.table, 
    relation: table_config.config.relation ? table_config.config.relation[schema.key] : null
  }, mini, index)).sort((a,b)=>a.sort - b.sort)
  tableExtended && tableExtended.forEach(ext=>{ 
    const exist = forms.findIndex(f=>ext.key ==f.key)
    if(exist >= 0){
      forms[exist] = {...forms[exist], ...ext}
    }else{
      forms.push(ext) 
    }
  })
  return forms.sort((a,b)=>a.sort - b.sort)
}